home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_09_10 / 9n10119b < prev    next >
Text File  |  1991-08-14  |  6KB  |  245 lines

  1.  
  2. #include <dos.h>
  3. #include <time.h>
  4. #include <stdio.h>     
  5. #include <bios.h>  
  6. #include <conio.h>
  7.  
  8. #define F10 0x0144 /* F10 key */
  9. #define F1 0x013b  /* F1 key */
  10. #define TRUE  1
  11. #define FALSE 0
  12. #define PJN_INTER 0x001C /* Timer interrupt */
  13. #define  NO_WAIT 0è#define  WAIT   1
  14. #define  CLEAR_WAIT  2
  15.  
  16. typedef struct {
  17.   unsigned key;
  18.   void (*function_ptr) ();
  19.   } PJN_KEYS;
  20.  
  21. static int on_key_flag =FALSE;
  22. extern PJN_KEYS *active_keys; /* Nominates active keys in calling program   */
  23.  
  24. void setup_screens(void);
  25. void output_screen(int i, int j);
  26. void print_message(void);
  27. void help_message(void);
  28. void press_a_key(int row);
  29. extern void on_key(void);
  30. extern void off_key(void);
  31. void check_key(void);
  32. void on_key(void);
  33. void off_key(void);
  34. unsigned GetKey( int fWait);
  35. void (interrupt far * old_handler) ();
  36. extern void (*pjn_next_fn)();
  37.  
  38. PJN_KEYS *active_keys; /* Pointer to pass active keys to functions in ON */
  39. void (*pjn_next_fn) () = NULL; /* Global function to pass to control loop */
  40.  
  41. main()
  42.   {
  43.    int i = 0;
  44.    int function;
  45.    static PJN_KEYS key_calls[] = { { F10, print_message},
  46.                { F1, help_message},
  47.                { ' ', NULL} 
  48.                };
  49.  
  50.    active_keys = key_calls; /* Nominate active keys */
  51.  
  52.    setup_screens ();
  53.  
  54.    on_key();
  55.  
  56.    do
  57.    {
  58.    output_screen(i, function);
  59.    i++;
  60.      
  61.    if (pjn_next_fn != NULL)
  62.       {
  63.       function = 1;
  64.       printf("Executing a function %lx", pjn_next_fn);
  65.       (*pjn_next_fn) (); /* go to next function if not Null */
  66.       }
  67.    } while (i < 100);
  68.    
  69.    off_key();
  70.  
  71.   }
  72.  
  73. /*_________Print message that required key pressed _____*/
  74. void print_message(void)
  75.   {è   off_key();
  76.    printf("System stopped with F10 key");
  77.    exit(99);
  78.   }
  79.  
  80. /*________Print help message_________________________*/
  81. void help_message(void)
  82.   {
  83.    off_key();
  84.    printf("Help message - F1");
  85.    on_key();
  86.    return;
  87.   }
  88.  
  89. /*_____________Paint initial screens _________________*/
  90. void setup_screens(void)
  91.   {
  92.   printf(" Demo program for keyboard interrupts");
  93.     press_a_key(10);
  94.   }
  95.  
  96. /*_________________Wait for a key press ________________*/
  97.  
  98. /* Note: New handler must be off if this is to work.*/
  99.  
  100. void press_a_key(int wrow)
  101.   {
  102.    printf(" Press a key");
  103.    GetKey(WAIT);
  104.   }
  105.  
  106. /*__________________Dummy screen output __________________*/
  107.  
  108. void output_screen(int i, int j)
  109.   {
  110.    printf("\nThe current value is %d function %d ", i, j);
  111.   } 
  112.  
  113. /*****************************************************************/
  114. /* ON KEY function similar to the Basic one */
  115.  
  116. /* NOTE:   When the keys are on, no returns are made to the 
  117.      input buffer. Therefore if a 'press a key' type
  118.      function is requiried, the keys must be turned off
  119.      first
  120. */
  121.  
  122.  
  123. /*______________New timer interrupt handler _________________*/
  124.  
  125. void interrupt far our_handler()
  126.   {
  127.    int i;
  128.    unsigned m_char;
  129.  
  130.    m_char = GetKey ( NO_WAIT );
  131.    
  132.    for( i = 0; i <= 10; i++)
  133.      {
  134.      if (m_char == active_keys[i].key)
  135.      pjn_next_fn = active_keys[i]. function_ptr;
  136.      /* Assign next fn ptr */
  137.      if (( active_keys[i].function_ptr) == NULL)è      return;
  138.      }
  139.    /* Not required, but nice to have */
  140.    _chain_intr(old_handler);
  141.    }
  142. /*__________________-Turn on new handler ____________________*/
  143.  
  144. void on_key(void)
  145.   {
  146.    if(on_key_flag)   /* Handler already loaded. */
  147.      {
  148.      off_key();
  149.      printf("\nYou cannot load the ON_KEY handler twice.");
  150.      printf("\nProgram aborted.");
  151.      exit(99);
  152.      }
  153.    printf(" Turning on key");
  154.  
  155.    old_handler = _dos_getvect(PJN_INTER);
  156.  
  157.    _disable();
  158.    _dos_setvect(PJN_INTER, our_handler);
  159.    _enable();
  160.    on_key_flag = TRUE;
  161.   }
  162. /*________________-Return old keyboard interrupthandler _____*/
  163.  
  164. void off_key( void)
  165.    {
  166.    printf(" Disabling");
  167.    _disable();
  168.    _dos_setvect (PJN_INTER, old_handler);
  169.    _enable();
  170.    on_key_flag = FALSE;
  171.    pjn_next_fn = NULL;
  172.    }
  173. /*_______________-Microsoft get key function _______________*/
  174. /* GetKey - Gets a key from the keyboard. This routine 
  175. * distinguishes between ASCII keys and function or control
  176. * keys with differenct shift states. It also accepts
  177. * a flag to return immediately if no key is available.
  178. *
  179. * Params: fWait - Code to indicate how to handle keyboard buffer:
  180. *  NO_WAIT   Return 0 if nokey in buffer, else return key
  181. *  WAIT     Return first key if available, else wait for key
  182. *  CLEAR_WAIT  Thow away any key in buffer and wait for new key
  183. *
  184. * Return: One of the following:
  185. *
  186. * Keytype               High Byte   Low Byte
  187. * _____________            _________   ________
  188. *
  189. * No key available (onlywith NO_WAIT)    0     0
  190. * ASCII value                0     ASCII code
  191. * Unshifted function or keypad       1     scan code
  192. * Shifted function orkeypad         2     scan code
  193. * CTRL function orkeypad          3     scan code
  194. * ALT function or keypad          4     scan code
  195. *
  196. * Note: getkey cannot return codes forkeys not recognized by 
  197. *     BIOS int 16, such as the CTRL-UP or the 5 key on the 
  198. *     numeric keypad>
  199. */èunsigned GetKey( int fWait)
  200.   {
  201.    unsigned uKey, uShift;
  202.  
  203.    /* If CLEAR_WAIT, drain the keyboard buffer. */
  204.    if( fWait == CLEAR_WAIT )
  205.      while( _bios_keybrd( _KEYBRD_READY ))
  206.         _bios_keybrd( _KEYBRD_READ );
  207.  
  208.    /* If NO-WAIT, return 0 if there is nokey ready. */
  209.    if ( !fWait && !_bios_keybrd( _KEYBRD_READY ))
  210.      return FALSE;
  211.  
  212.   /* Get key code. */
  213.   uKey = _bios_keybrd( _KEYBRD_READ );
  214.  
  215. /* If lowbyte is not zero, it's an ASCII key. Check scan code to 
  216. * see if it's on the numerickeypad. If not, clear high byte and
  217. * return.
  218. */
  219.  
  220.   if( uKey & 0x00ff )
  221.      if( (uKey >> 8) < 69 )
  222.        return( uKey & 0x00ff );
  223.  
  224. /* For function keys and numeric keypad, put scan code inlow byte
  225. * and shift state codes in high byte.
  226. */
  227.  
  228.   uKey >>= 8;
  229.   uShift = _bios_keybrd( _KEYBRD_SHIFTSTATUS ) & 0x000f;
  230.   switch( uShift )
  231.     {
  232.    case 0:
  233.      return ( 0x0100 | uKey ); /* None (1)  */
  234.    case 1:
  235.    case 2:
  236.    case 3:
  237.      return( 0x0200 | uKey ); /* Shift (2)  */
  238.    case 4:
  239.      return( 0x0300 | uKey ); /* Control (3) */
  240.    case 8:
  241.      return( 0x0400 | uKey ); /* Alt (4)   */ 
  242.     }
  243.   }
  244.  
  245.